<template>
  <m-toolbar class="v-graph-top-bar" :toolbar="toolbarData">
    <div v-show="showLegend"  class="legends">
      <div class="title">图例</div>
      <div v-for="item in legend" :key="item.key" style="height:20px">
        <div
          class="legend"
          :style="{
            borderBottomStyle: 'solid',
            borderBottomWidth: '3px',
            borderBottomColor: item.value,
            display: 'inline-block'
          }"
        ></div>
        <div style="display:inline-block">{{ item.name }}</div>
      </div>
    </div>
  </m-toolbar>
</template>
<script>
import graph from 'src/pages/mxgraph/graph/index';
import { cloneDeep } from 'lodash';
import toolBar from 'src/components/common/ToolBar';
import { actions } from '@/pages/mxgraph/Actions';
import { getStyleObj, getStyleStr } from '@/util/common';
import ResizeUtil from 'src/pages/mxgraph/resizeUtil';
import graphUtil from '@/pages/mxgraph/graphUtil';
import { GraphShapeUtil } from '@/pages/mxgraph/GraphShapeUtil';
import { behaviors } from '@/pages/mxgraph/behaviors';
import { saveImage } from '@/components/Attribute/modals/SaveImage';
const {
  mxEvent,
  mxCodec,
  mxUtils,
  mxCompactTreeLayout,
  mxCircleLayout,
  mxCompositeLayout,
  mxEdgeLabelLayout,
  mxFastOrganicLayout,
  mxParallelEdgeLayout,
  mxPartitionLayout,
  mxRadialTreeLayout,
  mxStackLayout,
  mxXmlRequest,
  mxXmlCanvas2D,
  mxImageExport
} = graph;
export default {
  name: 'top-bar',
  components: {
    'm-toolbar': toolBar
  },
  props: {
    ui: Object,
    graphContent: HTMLDivElement
  },
  data() {
    return {
      showLegend: false,
    
      btns: {
        zoom: {
          scale: 100,
          smallDisabled: true,
          largeDisabled: true,
        },
      },
      layouts: [
        {
          label: '紧凑树布局',
          value: 'CompactTree',
          layout: mxCompactTreeLayout,
        },
        {
          label: '圆形布局',
          value: 'Circle',
          layout: mxCircleLayout,
        },
        {
          label: '组合布局',
          value: 'Composite',
          layout: mxCompositeLayout,
        },
        {
          label: '边标签布局',
          value: 'EdgeLabel',
          layout: mxEdgeLabelLayout,
        },
        {
          label: '快速组织布局',
          value: 'FastOrganic',
          layout: mxFastOrganicLayout,
        },
        {
          label: '平行边布局',
          value: 'ParallelEdge',
          layout: mxParallelEdgeLayout,
        },
        {
          label: 'PartitionLayout',
          value: 'Partition',
          layout: mxPartitionLayout,
        },
        {
          label: 'RadialTreeLayout',
          value: 'Partition',
          layout: mxRadialTreeLayout,
        },
        {
          label: 'StackLayout',
          value: 'Stack',
          layout: mxStackLayout,
        }
      ],
      toolbarData: [
        {
          name: 'recall',
          key: 'recall',
          icon: 'statics/icons/app/toolbarrecall.svg',
          type: 'button',
          tips: '重做',
          des: '',
          width: '20px',
          fn: this.handleUndo,
          disabled: true,
        },
        {
          name: 'redo',
          key: 'redo',
          icon: 'statics/icons/app/toolbarredo.svg',
          type: 'button',
          tips: '撤销',
          des: '',
          width: '20px',
          fn: this.handleRedo,
          disabled: true,
        },
        {
          name: 'showModelPosition',
          key: 'showModelPosition',
          icon: 'statics/icons/table/showModelPosition.svg',
          type: 'button',
          tips: '树上高亮',
          des: '',
          width: '20px',
          disabled: true,
          fn: this.showModelPostion,
        },
        {
          name: 'iconlayout',
          key: 'iconlayout',
          icon: 'statics/icons/graph/iconlayout.svg',
          type: 'buttonList',
          tips: '布局',
          des: '',
          width: '36px',
          children: [
            {
              name: '横向',
            },
            {
              name: '纵向',
            },
            {
              name: '放射状',
            },
            {
              name: '按顺序',
            },
            {
              name: '环形',
            }
          ],
        },
        {
          name: 'toolbarcopy',
          key: 'toolbarcopy',
          icon: 'statics/icons/graph/toolbarcopy.svg',
          type: 'button',
          tips: '复制',
          des: '',
          width: '20px',
          fn: this.handleCopy,
          disabled: true,
        },
        {
          name: 'toolbarpaste',
          key: 'toolbarpaste',
          icon: 'statics/icons/graph/toolbarpaste.svg',
          type: 'button',
          tips: '粘贴',
          des: '',
          width: '20px',
          fn: this.handlePaste,
          disabled: true,
        },
        {
          name: 'deleteIcon',
          key: 'deleteIcon',
          icon: 'statics/icons/table/deleteRequirement.svg',
          type: 'button',
          tips: '删除',
          des: '',
          width: '20px',
          line: true,
          fn: this.handleDelete,
          disabled: true,
        },
        {
          name: 'removeIcon',
          key: 'removeIcon',
          icon: 'statics/icons/table/removeFromTable.svg',
          type: 'button',
          tips: '移出',
          fn: this.handleRemove,
          des: '移出',
          width: '50px',
          line: true,
          disabled: true,
        },
        {
          name: 'toolbarline',
          key: 'toolbarline',
          icon: 'statics/icons/graph/toolbarline.svg',
          type: 'buttonList',
          tips: '线型',
          des: '线型',
          width: '60px',
          line: true,
          children: [
            {
              name: '直线',
              fn: this.setEdgeStrait
            },
            {
              name: '折线',
              fn: this.setEdgePolygonal
            },
            {
              name: '弧线',
              fn: this.setEdgeArcable
            }
          ],
        },
        //// {
        ////   name: 'toolbarlayer',
        ////   key: 'toolbarlayer',
        ////   icon: 'statics/icons/graph/toolbarlayer.svg',
        ////   type: 'buttonList',
        ////   tips: '图层',
        ////   des: '图层',
        ////   width: '60px',
        ////   line: true,
        ////   children: [
        ////     {
        ////       name: '置于顶层',
        ////     },
        ////     {
        ////       name: '置于底层',
        ////     }
        ////   ],
        //// },
        {
          name: 'toolbarxalignment',
          key: 'toolbarxalignment',
          icon: 'statics/icons/graph/toolbarxalignment.svg',
          type: 'buttonList',
          tips: '水平对齐',
          des: '水平对齐',
          width: '90px',
          line: true,
          children: [
            {
              name: '左对齐',
              fn: () => this.graphAlign("horizontal", 'left')
            },
            {
              name: '水平居中',
              fn: () => this.graphAlign("horizontal", 'center')
            },
            {
              name: '右对齐',
              fn: () => this.graphAlign("horizontal", 'right')
            }
          ],
        },
        {
          name: 'toolbaryalignment',
          key: 'toolbaryalignment',
          icon: 'statics/icons/graph/toolbaryalignment.svg',
          type: 'buttonList',
          tips: '垂直对齐',
          des: '垂直对齐',
          width: '90px',
          line: true,
          children: [
            {
              name: '顶部对齐',
              fn: () => this.graphAlign("vertical", 'top')
            },
            {
              name: '垂直居中',
              fn: () => this.graphAlign("vertical", 'middle')
            },
            {
              name: '底部对齐',
              fn: () => this.graphAlign("vertical", 'bottom')
            }
          ],
        },
        {
          name: 'toolbarAutomaticsize',
          key: 'toolbarAutomaticsize',
          icon: 'statics/icons/graph/toolbarAutomaticsize.svg',
          type: 'button',
          des: '自动大小',
          tips: '自动大小',
          width: '80px',
          line: true,
          fn: this.autoSize,
        },
        {
          name: 'toolbarLegend',
          key: 'toolbarLegend',
          icon: 'statics/images/sysml/Legend.svg',
          type: 'button',
          des: '图例',
          tips: '图例',
          width: '60px',
          line: true,
          fn: this.toggleLegend,
        },
        {
          name: 'exportImage',
          key: 'exportImage',
          icon: 'statics/images/sysml/exportimages.svg',
          type: 'button',
          des: '导出图片',
          tips: '导出图片',
          width: '80px',
          line: true,
          fn: this.showSaveImageModal,
          disabled: !app.$globalConfig.isElectron,
        },
        {
          name: 'resize',
          key: 'resize',
          type: 'jsx',
          width: '72px',
          content: (h) => {
            return <a-tooltip placement="bottom" mouseEnterDelay={1}>
              <template slot="title">
                  缩放百分比
              </template>
              <div class="g-flex">
                <div class="_top-btn" onClick={this.handleZoomSmall}>
                  <img src="statics/icons/app/toolbarreduce.svg" class="_btn-img"/>
                </div>
                <div class="_top-btn scale">{this.btns.zoom.scale}%</div>
                <div class="_top-btn" onClick={this.handleZoomLarge}>
                  <img src="statics/icons/app/toolbarenlarge.svg" class="_btn-img"/>
                </div>
              </div>
            </a-tooltip>

            ;
          }

        }
      ],
    };
  },
  computed: {
    graph() {
      return this.ui.editor.graph;
    },
    legend(){
      //// let ac =  app.activeGraphTab.graph?.diagramNode.getChildNodeByTypeName("CommandAction");
      const arr = [
        { name: '动力测试总控', value: '#D48806' },
        { name: '控制系统', value: '#096DD9' },
        { name: '发射支持', value: '#7CB305' },
        { name: '垂直瞄准', value: '#CF1322' },
        { name: '测量系统', value: '#CF1322' },
        { name: '发射场工作', value: '#08979C' }
      ];
      return  arr;
    } 
  },
  mounted() {
    setTimeout(() => {
      this.ui.editor.undoManager.addListener(
        mxEvent.ADD,
        this.handleStepChange
      );
      this.ui.editor.undoManager.addListener(
        mxEvent.REDO,
        this.handleStepChange
      );
      this.ui.editor.undoManager.addListener(
        mxEvent.UNDO,
        this.handleStepChange
      );
      this.graph.view.addListener(mxEvent.SCALE, this.handleScale);
      this.graph
        .getSelectionModel()
        .addListener(mxEvent.CHANGE, this.handleSelectChange);
    }, 1000);
  },
  beforeDestroy() {
    if (this.ui.editor && this.ui.editor.undoManager){
      this.ui.editor.undoManager.removeListener(
        mxEvent.ADD,
        this.handleStepChange
      );
      this.ui.editor.undoManager.removeListener(
        mxEvent.REDO,
        this.handleStepChange
      );
      this.ui.editor.undoManager.removeListener(
        mxEvent.UNDO,
        this.handleStepChange
      );

    }

  },
  methods: {
    graphAlign(type, key){
      const selection =  this.ui.editor.graph.getSelectionModel();
      let { cells } = selection;
      if (cells.length > 0){
        const mainCells = cells.filter(cell => cell.parent.deep === 0);
        if (type === 'horizontal'){
          let leftX = 0;
          let rightX = 0;
          const leftBorder = mainCells.map(item => (item.geometry.x ));
          const rightBorder = mainCells.map(item => (item.geometry.x + item.geometry.width ));
          leftX = Math.min(...leftBorder);
          rightX = Math.max(...rightBorder);
          const type2positon = {
            left: leftX,
            right: rightX,
            center: (leftX + rightX) / 2
          };
          mainCells.forEach((cell) => {
            if (key === 'center'){
              cell.umlShape.box.boxX = type2positon[key] - (cell.umlShape.box.boxWidth / 2);
            } else  if ( key === 'right'){
              cell.umlShape.box.boxX = type2positon[key] - cell.umlShape.box.boxWidth;
            } else {
              cell.umlShape.box.boxX = type2positon[key];
            }
            ResizeUtil.updateBoundsByBox(cell.umlShape);
          });
        } else if ( type === 'vertical' ){
          let topY = 0;
          let bottomY = 0;
          const topBorder = mainCells.map(item => (item.geometry.y));
          const bottomBorder = mainCells.map(item => (item.geometry.y + item.geometry.height));
          topY = Math.min(...topBorder);
          bottomY = Math.max(...bottomBorder);
          const type2positon = {
            top: topY,
            bottom: bottomY,
            middle: (topY + bottomY) / 2
          };
          mainCells.forEach((cell) => {
            if (key === 'middle'){
              cell.umlShape.box.boxY = type2positon[key] - (cell.umlShape.box.boxHeight / 2);
            } else if (key === 'bottom'){
              cell.umlShape.box.boxY = type2positon[key] - cell.umlShape.box.boxHeight;
            } else {
              cell.umlShape.box.boxY = type2positon[key];
            }
            ResizeUtil.updateBoundsByBox(cell.umlShape);
          });
        }

      }
      this.$bus.emit('fresh-graph');
    },
    toggleLegend(){
      if (app.activeGraphTab.diagramType === 'RocketTD'){
        this.showLegend = !this.showLegend;
      } else {
        app.$messageBox.warn({
          text: '暂未提供此功能',
          title: '试用版',
        });
      }
    },
    handleUndo() {
      console.log('undo');
      this.$message.warn('暂不支持回退');
      //// this.ui.editor.undoManager.undo();
    },
    handleRedo() {
      this.$message.warn('暂不支持重做');
      //// this.ui.editor.undoManager.redo();
    },
    showModelPostion() {
      actions.getAction('selectOnTree').onKeyboardEvent(this.graph);
    },
    handleCopy() {},
    handlePaste() {},
    handleDelete() {

      actions.getAction('removeModel').onKeyboardEvent(this.graph);
    },
    handleRemove() {
      actions.getAction('removeShape').onKeyboardEvent(this.graph);
    },
    autoSize() {
      const selectedCells = this.graph.selectionModel.cells;
      const ansCells = selectedCells.filter(cell => { //// 只处理父元素
        return !selectedCells.find(ans => {
          return graphUtil.isAncestor(ans, cell);
        });
      });
      const mainShapes = ansCells.map(cell => GraphShapeUtil.getAbsoluteMainShape(cell.umlShape)).filter(i => i.owner);
      if ( mainShapes.length > 0){
        mainShapes.forEach(shape => {
          behaviors.get(shape.getTypeName()).move(shape, { x: shape.bounds.x, y: shape.bounds.y, width: 60, height: 40 },  true,  false, this.graph.diagramNode);
        });
        this.$bus.emit('fresh-graph');
      }
    },
    handleZoomSmall() {
      if (this.btns.zoom.scale <= 10) return;
      if (this.btns.zoom.scale < 20) {
        this.btns.zoom.scale = 10;
      } else {
        this.btns.zoom.scale -= 10;
      }
      this.ui.editor.graph.zoomTo(this.btns.zoom.scale / 100);
    },
    handleZoomLarge() {
      if (this.btns.zoom.scale >= 1000) return;
      if (this.btns.zoom.scale >= 900) {
        this.btns.zoom.scale = 1000;
      } else {
        this.btns.zoom.scale += 10;
      }
      this.ui.editor.graph.zoomTo(this.btns.zoom.scale / 100);
    },
    handleStepChange() {
      //// this.btns.undo.disabled = !this.ui.editor.undoManager.canUndo();
      this.toolbarData.find(
        (item) => item.key === 'recall'
      ).disabled = !this.ui.editor.undoManager.canUndo();
      //// this.btns.redo.disabled = !this.ui.editor.undoManager.canRedo();
      this.toolbarData.find(
        (item) => item.key === 'redo'
      ).disabled = !this.ui.editor.undoManager.canRedo();
      console.log('add step');
    },
    handleScale(graph, evt) {
      console.log(evt);

      this.btns.zoom.scale = parseInt(evt.properties.scale * 100) || 0;
    },
    handleSelectChange(graph, evt) {
      //// if (isReadOnlyMode()) return;
      const { added, removed } = evt.properties;
      const delNodeBtn = this.toolbarData.find((item) => item.key === 'deleteIcon');
      const removeShapeBtn = this.toolbarData.find((item) => item.key === 'removeIcon');
      const showModelPositionBtn = this.toolbarData.find((item) => item.key === 'showModelPosition');

      const selectedCells = this.graph.selectionModel.cells;

      console.log('select change');
      showModelPositionBtn.disabled = !(selectedCells[0] && selectedCells[0].umlShape && selectedCells[0].umlShape.container);

      if ( selectedCells.length === 0 || this.graph.selectionModel.cells.find((cell) => cell.umlShape === graph.diagramShape)) { //// 如果没有选中元素或选中了画布则禁用
        delNodeBtn.disabled = true;
        removeShapeBtn.disabled = true;
        return;
      }
      let delDisabled = false; //// 只要有一个元素是disabled删除模型按钮就禁用,画布不能删除
      let removeDisabled = false;
      let showModelPositionDisable = false;
      for (let i = 0; i < selectedCells.length; i++){

        const cell = selectedCells[i];
        if (cell.umlShape?.container?.disabled || cell.umlShape?.owner == null){
          delDisabled = true;
        }
        if (cell.umlShape.graphNode && app.configManager.getNotAllowDeleteTypes().includes(cell.umlShape.graphNode.getTypeName())){
          delDisabled = true;
        }
        if (cell.umlShape?.owner == null){
          removeDisabled = true;
        }
        if (cell.umlShape.getTypeName && app.configManager.getNotAllowDeleteShapeTypes().includes(cell.umlShape.getTypeName())){
          removeDisabled = true;
        }

      }
      delNodeBtn.disabled = delDisabled;
      removeShapeBtn.disabled = removeDisabled;
      //// if (selectedCells.forEach(cell => {
      ////   if (cell.umlShape?.container?.disabled){
      ////     delDisabled = true;
      ////   }
      //// }))

      ////   if (
      ////     this.graph.selectionModel.cells.length > 0 ||
      //// 	!this.graph.selectionModel.cells.find((cell) => cell.deep === 0)
      ////   ) {
      ////     this.toolbarData.find(
      ////       (item) => item.key === 'deleteIcon'
      ////     ).disabled = false;
      ////     this.toolbarData.find(
      ////       (item) => item.key === 'removeIcon'
      ////     ).disabled = false;
      ////   } else {
      ////     this.toolbarData.find(
      ////       (item) => item.key === 'deleteIcon'
      ////     ).disabled = true;
      ////     this.toolbarData.find(
      ////       (item) => item.key === 'removeIcon'
      ////     ).disabled = true;
      ////   }
      //// cells;
    },
    handleEditDiagram() {
      const graph = this.ui.editor.graph;
      const modelClone = cloneDeep(graph.getModel());
      Object.keys(modelClone.cells).forEach((key) => {
        this.removeUmlShape([modelClone.cells[key]]);
      });
      let enc = new mxCodec(mxUtils.createXmlDocument());
      let node = enc.encode(modelClone);

      let xml = mxUtils.getXml(node);
      console.log(xml);

      //// console.log(this.ui.actions.get('editDiagram'));
      //// console.log(this.ui.actions.get('editDiagram').funct);
      //// this.ui.actions.get('editDiagram').funct();
    },
    removeUmlShape(cells) {
      cells.forEach((cell) => {
        cell.umlShape = undefined;
        if (cell.children && cell.children.length > 0) {
          this.removeUmlShape(cell.children);
          //// cell.children.umlShape=undefined
        }
      });
    },
    handleClickLayout(item) {
      const graph = this.ui.editor.graph;
      const Layout = item.layout;
      let layout = new Layout(graph, false);
      layout.groupPadding = 60;
      layout.nodeDistance = 60;
      layout.resizeParent = false;
      layout.execute(graph.model.cells[graph.diagram.id]);
    },
    setEdgeStrait(){
      const selectedCells = this.graph.selectionModel.cells;
      const cell = selectedCells[0];
      if (!cell.edge) return;
      GraphShapeUtil.updateWaypoints(cell.umlShape, []);
      const style = getStyleObj(cell.umlShape.box.style);
      style.edgeStyle = 'polyline';
      style.arcSize = '0';
      cell.umlShape.box.style = getStyleStr(style);
      this.$bus.emit('fresh-graph');

    },
    setEdgePolygonal(){
      const selectedCells = this.graph.selectionModel.cells;
      const cell = selectedCells[0];
      if (!cell.edge) return;
      const style = getStyleObj(cell.umlShape.box.style);
      style.edgeStyle = 'orthogonalEdgeStyle';
      style.arcSize = '0';
      cell.umlShape.box.style = getStyleStr(style);
      this.$bus.emit('fresh-graph');

    },
    setEdgeArcable(){
      const selectedCells = this.graph.selectionModel.cells;
      const cell = selectedCells[0];
      if (!cell.edge) return;
      const style = getStyleObj(cell.umlShape.box.style);
      console.log(style);

      style.arcSize = '20';

      //// style.arcSize = 20 = 'orthogonalEdgeStyle';
      cell.umlShape.box.style = getStyleStr(style);
      this.$bus.emit('fresh-graph');

    },

    showSaveImageModal() {
      saveImage.popup({ graph: this.graph, graphContent: this.graphContent }).then(res => {
        
      });
    },
  },
};
</script>
<style lang="scss">
.v-graph-top-bar {
	//// background: #d4ebf8;
	//// height: 32px;
	//// padding: 8px;
	//// border-bottom: 1px solid rgb(177, 206, 226);
  ._btn-img {
    position: relative;
    top: -2px;
    margin: 0 2px;
  }
  .legends {
    max-height: 186px;
    width: 156px;
    position: absolute;
    top: 40px;
    right: 10%;
    box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05),
      0px 6px 16px 0px rgba(0, 0, 0, 0.08), 0px 3px 6px -4px rgba(0, 0, 0, 0.12);
    border: 1px solid #c2d1da;
    background: #ffffff;
    //// padding-left: 17px;
    padding-top: 4px;
    padding-bottom: 20px;
    z-index: 2;
    .title {
      text-align: center;
      font-size: 12px;
      font-family: PingFangSC-Medium, PingFang SC;
      font-weight: 500;
      color: #000000;
      line-height: 20px;
      margin-bottom: 10px;
    }
    .legend {
      margin-left: 17px;
      margin-right: 10px;
      vertical-align: middle;
      width: 40px;
      height: 3px;
    }
  }
}
</style>
